/**
 * Description:
 * Class Name:ForkJoinPoolTest
 * Date:2022/5/8 17:16
 *
 * @author LTisme
 * @version JAVA17
 */
package 疯狂Java讲义.第16章_多线程._16_8_线程池._16_8_2_使用ForkJoinPool;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.TimeUnit;

// 小任务是没有返回值的打印任务，所以可以继承自RecursiveAction
class PrintTask extends RecursiveAction{
    // 设置小任务具体有多小
    private static final int THRESHOLD = 50;
    private int start;
    private int end;
    // 打印从start到end的任务
    public PrintTask(int start, int end){
        this.start = start;
        this.end = end;
    }

    @Override
    protected void compute() {
        // 当end与start之间的差小于THRESHOLD时，开始打印
        if (end - start < THRESHOLD){
            for (int i = start; i < end; i++) {
                System.out.println(Thread.currentThread().getName() + "_" + i);
            }
        }
        else {
            // 当end 与 start 之间的差大于THRESHOLD时，需要进行分解
            int middle = (start + end) / 2;
            var left = new PrintTask(start, middle);
            var right = new PrintTask(middle, end);
            // 并行执行两个小任务
            left.fork();
            right.fork();
//            left.compute();
//            right.compute();
        }
    }
}

public class ForkJoinPoolTest {
    public static void main(String[] args) throws InterruptedException {
        // 使用当前机器的处理器数量创建并行线程池
        var pool = new ForkJoinPool();
        // 提交可分解的PrintTask任务
        pool.submit(new PrintTask(0, 300));
        pool.awaitTermination(2, TimeUnit.SECONDS);
        // 关闭线程池
        pool.shutdown();
    }
}
